package com.ejuornal.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;

import com.ejuornal.bean.Page;
import com.ejuornal.dao.BaseDao;
/**    
 * 项目名称：ejuornal    
 * 类名称：DaoSupport    
 * 类描述：dao层的公共类 ，此类的主要功能为各个模块的dao实现层提供基类，为各个模块提供通用的增删改查   
 * 创建人：陈晨    
 * 创建时间：Jan 19, 2013 3:43:10 PM    
 * 修改人：陈晨    
 * 修改时间：Jan 19, 2013 3:43:10 PM    
 * 修改备注：    
 * @version     
 */
public abstract class DaoSupport<T> implements BaseDao<T>{
   
    private JdbcTemplate jdbcTemplate;
    /**
     * Title:add
     * Description:增加记录
     * @param sql
     * @param objs
     * void
     */
    public void add(String sql, Object... objs) {
       this.getJdbcTemplate().update(sql, objs);
    }
    /**
     * Title:batchDelete
     * Description:通过id批量删除记录
     * @param sql
     * @param ids
     * void
     */
    public void batchDelete(String sql ,final int...ids) {
        this.getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
            public void setValues(PreparedStatement ps, int i) throws SQLException {
               ps.setInt(1, ids[i]);
            }
            public int getBatchSize() {
                return ids.length;
            } 
        });
    }
    /**
     * Title:update
     * Description:更新记录
     * @param sql
     * @param objs
     * void
     */
    public void update(String sql, Object... objs) {
        this.getJdbcTemplate().update(sql, objs);
    } 
    
    /**
     * 普通查询，不需要传递参数，默认值每页10条记录
     */
    public Page<T> find(int current_record, String url) {
        return find(current_record, url, "", null);
    }
    /**
     * 普通查询，需要传递参数，默认值每页10条记录
     */
    @SuppressWarnings("unchecked")
    public Page<T> find(int current_record, String url, String hsql, Object[] objs) {
        Page<T> page = new Page<T>();
        int pageSize = page.getPageSize();
        ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
        String s = type.getActualTypeArguments()[0].toString();
        s = s.substring(s.lastIndexOf(".") + 1);
        StringBuffer sb = new StringBuffer();
        sb.append('t');
        for(int i=0; i < s.length(); i++) {
            char c = s.charAt(i);
            if(Character.isUpperCase(c)) {
                sb.append("_" + Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        String sql = "select count(*) from " + sb + " " + hsql;
        int totalRecords = this.getJdbcTemplate().queryForInt(sql, objs);
        
        sql = "select * from " + sb + " " + hsql + " limit " + current_record + "," + pageSize;
        List<T> list = null;
        if("".equals(hsql)) {
            list = (List<T>) this.getJdbcTemplate().queryForList(sql);
        } else {
            list = (List<T>) this.getJdbcTemplate().queryForList(sql, objs);
        }
        page.setUrl(url);
        page.setTotalRecords(totalRecords);
        page.setTotalPage(totalRecords);
        page.setRecords(list);
        return page;
    }
    
  
    @SuppressWarnings("unchecked")
    public Page<T> find5(int current_record, String url, String hsql, Object[] objs) {
        Page<T> page = new Page<T>();
        page.setPageSize(5);
        
        int pageSize =page.getPageSize();
        ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
        String s = type.getActualTypeArguments()[0].toString();
        s = s.substring(s.lastIndexOf(".") + 1);
        StringBuffer sb = new StringBuffer();
        sb.append('t');
        for(int i=0; i < s.length(); i++) {
            char c = s.charAt(i);
            if(Character.isUpperCase(c)) {
                sb.append("_" + Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        
        

        String sql = "select count(*) from " + sb + " " + hsql;
        int totalRecords = this.getJdbcTemplate().queryForInt(sql, objs);
        
        sql = "select * from " + sb + " " + hsql + " limit " + current_record + "," + pageSize;
        List<T> list = null;
        if("".equals(hsql)) {
            list = (List<T>) this.getJdbcTemplate().queryForList(sql);
        } else {
            
            list = (List<T>) this.getJdbcTemplate().queryForList(sql, objs);
        }
        page.setUrl(url);
        page.setTotalRecords(totalRecords);
        page.setTotalPage(totalRecords);
        page.setRecords(list);
        return page;
    }
    
    /**
     * 查询，需要传入总个数和前几条记录的sql，分页默认是每页10条
     * @param current_record
     * @param url
     * @param sql_1
     * @param sql_2
     * @param objs
     * @return
     */
    public Page<T> find(int current_record, String url, String sql_1, String sql_2, Object[] objs) {
    	return find (current_record, url, 10, sql_1, sql_2, objs);
    }
    
    /**
     *  查询，需要传入总个数和前几条记录的sql，分页中每页的个数是传递参数
     * @param current_record
     * @param url
     * @param pageSize
     * @param sql_1
     * @param sql_2
     * @param objs
     * @return
     */
    public Page<T> find (int current_record, String url, int pageSize, String sql_1, String sql_2, Object[] objs) {
   	 Page<T> page = new Page<T>();
        @SuppressWarnings("deprecation")
		int totalRecords = this.getJdbcTemplate().queryForInt(sql_1, objs);
        @SuppressWarnings("unchecked")
		List<T> list = (List<T>) this.getJdbcTemplate().queryForList(sql_2, objs);
        page.setPageSize(pageSize);
        page.setUrl(url);
        page.setTotalRecords(totalRecords);
        page.setTotalPage(totalRecords);
        page.setRecords(list);
        return page;
   }
    
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }
    
    @Resource
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}
